// 编译器
//
// 编译器是 Angular 提供的一项服务，用来遍历DOM节点，查找特定的属性。编译过程分为两个阶段：
//
// 编译：遍历DOM节点，收集所有的指令，返回一个连接函数（link func）
//
// 连接：将上一步收集到的每个指令与其所在的作用域（scope）连接生成一个实时视图。
// 任何作用域中的模型改变都会实时在视图中反映出来，同时任何用户与视图的交互则会映射到作用域的模型中。
// 这样，作用域中的数据模型就成了唯一的数据源。
// 一些如 ng-repeat 这样的指令，会为集合中的每个项目克隆一次DOM元素。
// 由于克隆的模板只需要被编译一次，然后为每个克隆实例做一次连接，这样将编译分成编译和连接两个阶段就有效地提升了性能
// （译注：不用为每个克隆的实例都编译一次，只需对模板进行统一的一次编译，然后在连接阶段单独为每个实例进行到 scope 的连接即可）。


var i = 0;

var myApp = angular.module('myApp', [])
    .directive('customTags',function () {
        return {
            restrict : 'ECAM',
            template : '<div>{{user.name}}</div>',
            replace: true,
            //如果compile里面定义了return function(){}，link就没用了。
            // 因为compile里面定义的是link函数
            compile:function (tElement,tArrs,transclude) {
                // JQLite [div]
                // console.log(tElement);
                // //Attributes {$$element: JQLite(1), $attr: {…}, ngRepeat: "user in users", customTags: "", customTags2: ""}
                // console.log(tArrs);
                // // false
                // console.log(transclude);

                //编译阶段：对模板进行结构上的变化
                console.log("customTags  compile  编译阶段");

                //可以在compile中改变当前dom的结构，要改变这个复杂的dom结构，必须在compile里面做
                tElement.append(angular.element('<div>{{user.name}} {{user.count}}</div>'))
                //整个元素结构会插入aaa，

                return {
                    // 表示在编译阶段之后，指令连接到子元素之前运行
                    pre : function preLink(scope,iElement,iAttrs,controller) {
                        console.log('customTags preLink..')
                    },
                    //表示会在所有子元素指令都连接之后才运行
                    post : function postLink(scope,iElement,iAttrs,controller) {

                        //iElement元素是ng-repeat所在的div元素
                        iElement.on('click',function () {
                            console.log(scope.user);
                            scope.$apply(function () {
                                scope.user.name = 'click after';

                                //每click一次，便会执行一次post
                                //post每执行一次，i都会++
                                scope.user.count = ++i;
                            //    进行一次脏检查
                            })
                        })

                        console.log('customTags all child directive link..')
                    }
                }
                // //可以直接返回postLink
                // return function () {
                //     //如果返回一个function，共执行repeat的次数
                //     console.log('compile return fun')
                // }
            },
            //此link表示的就是postLink
            link:function () {

            }
        }

    })
    .directive('customTags2',function () {
        return {
            restrict : 'ECAM',
            replace: true,
            //如果compile里面定义了return function(){}，link就没用了。
            // 因为compile里面定义的是link函数
            compile:function () {
//编译阶段：对模板进行结构上的变化
                console.log("customTags2  compile  编译阶段");

                return {
                    // 表示在编译阶段之后，指令连接到子元素之前运行
                    pre : function preLink(scope,iElement,iAttrs,controller) {
                        console.log('customTags2 preLink..')
                    },
                    //表示会在所有子元素指令都连接之后才运行
                    post : function postLink(scope,iElement,iAttrs,controller) {
                        console.log('customTags2 all child directive link..')
                    }
                }
            },
            link:function () {

            }
        }

    })
    //如果在directive里面返回的不是对象，而返回的是function，那么返回的function就是postLink
    .directive('customTags3',function(){
        //return postLink
        return function () {
            
        }
    })
    .controller('firstController',['$scope',function ($scope) {
        $scope.users = [
            {
                id:10,
                name:'张三'
            } ,
            {
                id:20,
                name:'李四'
            }
            // ,
            // {
            //     id:30,
            //     name:'王五'
            // }
        ]
    }])

// customTags  compile  编译阶段  1
// customTags2  compile  编译阶段  2
// customTags preLink..  3
// customTags2 preLink..  4
// customTags2 all child directive link..  5
// customTags all child directive link..  6
// customTags preLink..    7
// customTags2 preLink..   8
// customTags2 all child directive link..  9
// customTags all child directive link..  10
// 首先执行编译阶段  1-2
// 第一步取得里面所有的指令，根据优先级去执行compile：ng-repeat custom-tags custom-tags2
// 上述三个指令做完以后，还没有link，只是把整个页面转换出来。
// 其实就是把页面的结构显示出来。但是数据模板其实还没有连接
// link次数为ng-repeat复制元素的次数
// 然后执行第一个元素的link过程  3-6  ng-repeat postLink
// 当前的scope link 当前的子元素 customTags preLink.. customTags preLink..
// link完所有子元素后，然后原路返回各个元素的postLink
// 最后执行第二个元素的link过程  7-10  ng-repeat postLink